package com.spzx.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.product.api.domain.CategoryVo;
import com.spzx.product.domain.Category;
import com.spzx.product.domain.CategoryExcelVo;
import com.spzx.product.helper.CategoryHelper;
import com.spzx.product.listeners.CategoryExcelListener;
import com.spzx.product.mapper.CategoryMapper;
import com.spzx.product.service.ICategoryService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author ChenXing
 * @Description
 * @Create 2024/7/28 0:00
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;


    @Override
    public List<Category> treeSelect(Long parentId) {
        // 此时查到的是二级（自己理解的），但不确定，二级下面是否还有，就要继续判断下面是否还有字节点
        List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, parentId));
        // 遍历 categoryList 中的每一个 Category 看是否还有下面的子节点（一定要对着表格进行理解）
        for (Category category : categoryList) {
            // 查下面还有多少下级节点数
            Long count = categoryMapper.selectCount(new QueryWrapper<Category>().eq("parent_id", category.getId()));
            // 如果 count 大于0，说明当前的 Category 对象有子类别，因此调用 setHasChildren 方法设置 hasChildren 属性为 true，否则设置为 false。
            category.setHasChildren(count > 0);
        }
        return categoryList;
    }

    @Override
    public List<Long> getAllCategoryIdList(Long category3Id) {

 /*       // 传进来的是最后一级(第三级)的id，得到最后一级的 Category
        Category category3 = categoryMapper.selectOne(new QueryWrapper<Category>().eq("id", category3Id));
        Long category2Id = category3.getParentId();

        // 得到第二级 Category 通过第二级的id，再得到第一级的 id
        Category category2 = categoryMapper.selectOne(new QueryWrapper<Category>().eq("id", category2Id));
        Long category1Id = category2.getParentId();

        List<Long> list = new ArrayList<>();
        list .add(category1Id);
        list .add(category2Id);
        list .add(category3Id);*/


        /*
         * 实际情况下，你并不知道要查多少级，所有这个时候就需要使用递归调用
         *
         * */

        List<Long> list = new ArrayList<>();

        // 这个小车就是一个中途装数据的工具
        List<Category> car = new ArrayList<>();

        List<Category> categoryList = getParentCategory(category3Id, car);
        for (Category category : categoryList) {
            list.add(category.getId());
        }


        Collections.reverse(list);


        return list;

    }


    /*
     *   递归调用方法，获得所有级别的 id
     *   传入的最后一级的  id
     * */
    private List<Category> getParentCategory(Long categoryId, List<Category> car) {
        if (categoryId > 0) {
            Category category = categoryMapper.selectOne(new QueryWrapper<Category>().eq("id", categoryId));
            car.add(category);
            getParentCategory(category.getParentId(), car);
        }
        return car;
    }

    @SneakyThrows
    @Override
    public void exportData(HttpServletResponse response) {



//      CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
        List<CategoryExcelVo> categoryExcelVos;
        categoryExcelVos = categoryMapper.selectList(null).stream().map(category -> {
            CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
            BeanUtils.copyProperties(category, categoryExcelVo);
            return categoryExcelVo;
        }).collect(Collectors.toList());


        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("分类数据", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        EasyExcel.write(response.getOutputStream(), CategoryExcelVo.class).sheet("分类数据").doWrite(categoryExcelVos);

    }

    @Override
    public void importFile(MultipartFile multipartFile) {

        InputStream inputStream = null;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        EasyExcel.read(inputStream,CategoryExcelVo.class,new CategoryExcelListener(baseMapper)).sheet("分类数据").doRead();



    }

    @Override
    public List<CategoryVo> getOneCategory() {


        List<Category> categoryList = baseMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, 0));
        List<CategoryVo> categoryVoList = categoryList.stream().map(category -> {
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(category, categoryVo);
            return categoryVo;
        }).collect(Collectors.toList());
        return categoryVoList;
    }

    @Override
    public List<CategoryVo> tree() {

        // 这个树状，自己还要琢磨琢磨，看看接口文档，再看看页面效果
        // 一级分类中，children属性包含所有二级分类的集合，所有二级分类 children 属性包含所有三级分类的集合 ……
        // 明白需求后，这就是一个算法题

        List<Category> categoryList = categoryMapper.selectList(null);

        List<CategoryVo> categoryVoList = categoryList.stream().map(category -> {
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(category, categoryVo);
            return categoryVo;
        }).collect(Collectors.toList());

        return CategoryHelper.buildTree(categoryVoList);

    }

}






